﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;
using System.Data;

namespace HTToPdf
{
    class JHTToPDF
    {
        Common Init = new Common();

        private static Document doc;
        private static PdfPTable table;
        string[] content;
        float[] SetTotalWidth;//设定每列宽度
        int[] BorderSide;//设定每列边框
        int[] HAlign;
        string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory);
        public Common.Model model = null;

        private static BaseFont titleBaseFont = BaseFont.CreateFont("C://WINDOWS//Fonts//simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);//黑体

        /// <summary>
        /// 创建PDF
        /// </summary>
        /// <param name="dtSource">数据源</param>
        /// <returns></returns>
        public bool CreatePDF(string SaveFileName, Common.Model model, DataTable dtSource)
        {
            this.model = model;
            bool flag = false;
            try
            {
                doc = new Document(PageSize.A4, 10, 10, 10, 10);//定义一个Document，并设置页面大小为A4，竖向
                MemoryStream pdfMS = new MemoryStream();
                PdfWriter writer = PdfWriter.GetInstance(doc, pdfMS);//PDF内容放入到流中
                doc.Open();

                PageHeader();

                int emptyRow = 10;//如果table的行数小于20行，那么剩余部分显示空白行
                int sortNo = 0;//序号
                int Total = 8;

                SetTotalWidth = new float[] { 30, 105, 100, 110, 30, 40, 45, 60, 60 };//设定每列宽度
                BorderSide = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 ,0,0};//设定每列边框
                HAlign = new int[] { Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_RIGHT, Element.ALIGN_RIGHT, Element.ALIGN_RIGHT, Element.ALIGN_MIDDLE };
                if (dtSource.Rows.Count > 0)
                {
                    for (int i = 0; i < dtSource.Rows.Count; i++)
                    {
                        if (i % Total == 0 && i != 0)
                        {
                            PageFooter();
                            doc.NewPage();
                            PageHeader();
                        }

                        sortNo++;
                        content = new string[] { (i + 1).ToString(), dtSource.Rows[i]["spmch"].ToString(), dtSource.Rows[i]["shpgg"].ToString(), dtSource.Rows[i]["shengccj"].ToString(), dtSource.Rows[i]["dw"].ToString(), dtSource.Rows[i]["shl"].ToString(), dtSource.Rows[i]["hshj"].ToString(), dtSource.Rows[i]["hsje"].ToString(), dtSource.Rows[i]["pihao"].ToString() };
                        table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 10), HAlign);
                        doc.Add(table);
                    }
                }
                if (dtSource.Rows.Count % Total != 0)//说明数据源不足10行
                {
                    emptyRow = Total - dtSource.Rows.Count % Total;//如果为负数，说明不需要生成空白行
                    for (int i = 0; i < emptyRow; i++)
                    {
                        content = new string[] { (dtSource.Rows.Count + i + 1).ToString(), "", "", "", "", "", "", "", "" };
                        table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 10), HAlign);
                        doc.Add(table);
                    }
                }

                PageFooter();

                doc.Close();
                byte[] fileByte = pdfMS.GetBuffer();
                FileStream fs = new FileStream(SaveFileName, FileMode.Create);
                BinaryWriter bw = new BinaryWriter(fs);
                bw.Write(fileByte);
                bw.Close();
                fs.Close();
                flag = true;
            }
            catch (Exception ex)
            {
                Init.WriteLog(ex.ToString(), true);
            }
            return flag;
        }

        #region 文件头
        public void PageHeader()
        {
            CreateEmptyRow(1);//生成一行空行
            AddHeaderTitleContent("四川金仁医药集团有限公司退货函", 1, 15, Font.BOLD);//添加表头
            CreateEmptyRow(1);//生成一行空行

            content = new string[] {"函号：", model.djbh};
            SetTotalWidth = new float[] { 480, 100 };//设定每列宽度
            BorderSide = new int[] { 15, 13 };//设定每列边框
            HAlign = new int[] {  Element.ALIGN_RIGHT, Element.ALIGN_LEFT };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 12), HAlign);
            doc.Add(table);
            CreateEmptyRow(1);//生成一行空行

            content = new string[] { model.dwmch+"：","" };
            SetTotalWidth = new float[] { 480,100 };//设定每列宽度
            BorderSide = new int[] { 13,15 };//设定每列边框
            HAlign = new int[] { Element.ALIGN_LEFT, Element.ALIGN_LEFT };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 12), HAlign);
            doc.Add(table);


            string contents = "        贵公司与我公司（四川金仁医药集团有限公司）在近期的药品采购合作中，共产生";
            AddHeaderTitleContent(contents, 0, 14, Font.NORMAL);//添加表头 
           
            

                SetTotalWidth = new float[] { 80, 80, 420 };//设定每列宽度
            BorderSide = new int[] { 15, 13, 15};//设定每列边框
            HAlign = new int[] { Element.ALIGN_RIGHT, Element.ALIGN_CENTER, Element.ALIGN_LEFT };
            content = new string[] { "金额为", model.hsje, "元（详见采退清单）的药品退货。为了双方的友好合作，现特通" };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 14), HAlign);
            doc.Add(table);

            SetTotalWidth = new float[] { 410, 20, 150 };//设定每列宽度
            BorderSide = new int[] { 15, 13, 15 };//设定每列边框
            HAlign = new int[] { Element.ALIGN_RIGHT, Element.ALIGN_CENTER, Element.ALIGN_LEFT };
            content = new string[] { "知贵公司，需要在收到本退货函之日起三十日内选择以下第", "", "种方式处理该笔货物：" };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 14), HAlign);
            doc.Add(table);

            contents = "        1、自提；";
            AddHeaderTitleContent(contents, 0, 14, Font.NORMAL);//添加表头
            contents = "        2、委托我司自行处理该批货物；";
            AddHeaderTitleContent(contents, 0, 14, Font.NORMAL);//添加表头



            contents = "        3、";
            AddHeaderTitleContent(contents, 0, 14, Font.NORMAL);//添加表头

            contents = "        退货结束后三十天内，贵公司须通过电汇、票折或负数发票形式支付此笔货款。";
            AddHeaderTitleContent(contents, 0, 14, Font.NORMAL);//添加表头

            contents = "        如贵公司未在三十日内将该批货物处理，我公司有权自行处理，包括但不限于销毁、自行托运等，因此产生的费用及退货金额，我公司有权在后续业务往来款中自行扣除，或要求贵公司通过票折或负数发票形式支付。";
            AddHeaderTitleContent(contents, 0, 14, Font.NORMAL);//添加表头

            CreateEmptyRow(1);//生成一行空行

            contents = " 附退货商品如下：";
            AddHeaderTitleContent(contents, 0, 12, Font.BOLD);//添加表头
            CreateEmptyRow(1);//生成一行空行
            //30, 100, 90, 30, 60, 50, 60, 160
            content = new string[] { "序号", "商品名称", "商品规格", "生产企业", "单位", "数量", "单价", "金额","批号" };
            SetTotalWidth = new float[] { 30, 105, 100, 110, 30, 40, 45, 60, 60 };//设定每列宽度
            BorderSide = new int[] { 0, 0, 0, 0, 0, 0, 0, 0,0 };//设定每列边框
            HAlign = new int[] { Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, Element.ALIGN_MIDDLE, Element.ALIGN_MIDDLE, Element.ALIGN_MIDDLE };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 10), HAlign);
            doc.Add(table);
        }
        #endregion

        #region 文件尾
        public void PageFooter()
        {
            SetTotalWidth = new float[] { 135, 325, 60, 60 };//设定每列宽度
            BorderSide = new int[] { 0, 0, 0, 0 };//设定每列边框
            HAlign = new int[] { Element.ALIGN_RIGHT, Element.ALIGN_LEFT, Element.ALIGN_RIGHT, Element.ALIGN_LEFT };
            content = new string[] { "合计金额：", Init.NumtoChinese(decimal.Parse(model.hsje)), model.hsje, "" };
           // content = new string[] { "合计金额：", model.hsje, model.hsje, "" };
            //content = new string[] { "合计金额：", Init.NumtoChinese(decimal.Parse(model.hsje)) + "（" + model.hsje + "）" };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 10), HAlign);
            doc.Add(table);

            CreateEmptyRow(1);//生成一行空行

            SetTotalWidth = new float[] {60,80, 150, 290 };//设定每列宽度
            BorderSide = new int[] {15, 15, 13, 15 };//设定每列边框
            HAlign = new int[] { Element.ALIGN_LEFT, Element.ALIGN_LEFT, Element.ALIGN_RIGHT, Element.ALIGN_LEFT };
            //content = new string[] { "合计金额：", Init.NumtoChinese(decimal.Parse(model.hsje)), model.hsje, "" };
            content = new string[] { "","签收人：", "(公章)", "" };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 14), HAlign);
            doc.Add(table);

            SetTotalWidth = new float[] { 60, 80, 150, 290 };//设定每列宽度
            BorderSide = new int[] { 15, 15, 13, 15 };//设定每列边框
            HAlign = new int[] { Element.ALIGN_LEFT, Element.ALIGN_LEFT, Element.ALIGN_RIGHT, Element.ALIGN_LEFT };
            //content = new string[] { "合计金额：", Init.NumtoChinese(decimal.Parse(model.hsje)), model.hsje, "" };
            content = new string[] { "", "签收人委托处理退货事宜人：", "", "" };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 14), HAlign);
            doc.Add(table);

            CreateEmptyRow(1);//生成一行空行
            SetTotalWidth = new float[] {60,80, 40,20,30,20,30, 300 };//设定每列宽度
            BorderSide = new int[] {15, 15, 13, 15,13,15,13,15 };//设定每列边框
            HAlign = new int[] { Element.ALIGN_LEFT, Element.ALIGN_LEFT, Element.ALIGN_RIGHT, Element.ALIGN_LEFT, Element.ALIGN_LEFT, Element.ALIGN_LEFT, Element.ALIGN_LEFT, Element.ALIGN_LEFT };
            //content = new string[] { "合计金额：", Init.NumtoChinese(decimal.Parse(model.hsje)), model.hsje, "" };
            content = new string[] {"", "签收时间：", "", "年", "", "月", "", "日" };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 14), HAlign);
            doc.Add(table);

            CreateEmptyRow(1);//生成一行空行
            CreateEmptyRow(1);//生成一行空行
            CreateEmptyRow(1);//生成一行空行

            SetTotalWidth = new float[] { 520, 60 };//设定每列宽度
            BorderSide = new int[] { 15, 15};//设定每列边框
            HAlign = new int[] { Element.ALIGN_RIGHT, Element.ALIGN_LEFT };
            //content = new string[] { "合计金额：", Init.NumtoChinese(decimal.Parse(model.hsje)), model.hsje, "" };
            content = new string[] {"四川金仁医药集团有限公司" , "" };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 14), HAlign);
            doc.Add(table);
            CreateEmptyRow(1);//生成一行空行
            SetTotalWidth = new float[] { 280, 80, 40, 20, 30, 20, 30, 80 };//设定每列宽度
            BorderSide = new int[] { 15, 15, 13, 15, 13, 15, 13, 15 };//设定每列边框
            HAlign = new int[] { Element.ALIGN_LEFT, Element.ALIGN_LEFT, Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_CENTER, Element.ALIGN_LEFT };
            //content = new string[] { "合计金额：", Init.NumtoChinese(decimal.Parse(model.hsje)), model.hsje, "" };
            content = new string[] { "", "", model.rq.Substring(0, 4), "年", model.rq.Substring(5, 2), "月", model.rq.Substring(8, 2), "日" };
            table = AddTableHeader(content, SetTotalWidth, BorderSide, new Font(titleBaseFont, 14), HAlign);
            doc.Add(table);

            iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(@path + "\\sitamp2.dll");
            img.SetAbsolutePosition((doc.PageSize.Width / 2) + 80, (doc.PageSize.Height / 2) - 360);
            img.ScaleToFit(110F, 110F);
            //img.GrayFill = 20;
            doc.Add(img);
        }
        #endregion

        #region 生成水印
        /// <summary>
        /// 设置pdf图片水印
        /// </summary>
        /// <param name="imgPath">水印图片路径</param>
        /// <param name="filePath">需要添加水印的pdf文件</param>
        /// <param name="outfilePath">添加完成的pdf文件</param>
        /// <returns></returns>
        public static bool SetImgWaterMark(string imgPath, string filePath, string outfilePath)
        {
            PdfReader pdfReader = null;
            PdfStamper pdfStamper = null;
            FileStream fileStream = null;
            try
            {
                pdfReader = new PdfReader(filePath);
                fileStream = new FileStream(outfilePath, FileMode.Create);
                pdfStamper = new PdfStamper(pdfReader, fileStream);
                int total = pdfReader.NumberOfPages;
                Rectangle psize = pdfReader.GetPageSize(1);
                float width = psize.Width;
                float height = psize.Height;
                PdfContentByte content;
                //获取水印图片
                Image image = Image.GetInstance(imgPath);
                image.SetAbsolutePosition((doc.PageSize.Width / 2) - 150, (doc.PageSize.Height / 2) - 340);
                image.ScaleToFit(110F, 110F);
                image.GrayFill = 20;

                for (int i = 1; i <= total; i++)
                {
                    content = pdfStamper.GetOverContent(i);//在内容上方加水印
                    //content = pdfStamper.GetUnderContent(i);//在内容下方加水印
                    content.AddImage(image);
                }
                return true;
            }
            catch (Exception ex)
            {
                //Common.WriteLogs(ex.ToString(), true);
                outfilePath = "";
                return false;
            }
            finally
            {
                if (pdfStamper != null)
                {
                    pdfStamper.Close();
                }
                if (pdfReader != null)
                {
                    pdfReader.Close();
                }
                if (fileStream != null)
                {
                    fileStream.Close();
                    fileStream.Dispose();
                }
            }
        }
        #endregion


        #region 生成N行空白行
        private static void CreateEmptyRow(int emptyRowNum)
        {
            for (int i = 0; i < emptyRowNum; i++)
            {
                doc.Add(new Paragraph(" "));
            }
        }
        #endregion

        #region 生成标题
        /// <summary>
        /// 
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="Alignment">对齐 0居左，1居中，2居右</param>
        /// <param name="FontSize">字体大小</param>
        /// <param name="style">样式</param>
        private static void AddHeaderTitleContent(string content, int Alignment, int FontSize, int style)
        {
            Paragraph p = new Paragraph(content, new Font(titleBaseFont, FontSize, style));
            p.Alignment = Alignment;
            doc.Add(p);
        }
        #endregion

        #region 生成表格头
        private static PdfPTable AddTableHeader(string[] content, float[] colSet, int[] BorderSide, Font font, int[] horizontalAlignment)
        {
            int count = content.Count();
            PdfPTable table = new PdfPTable(count);//列的table
            //添加表格列头               
            //table.SetTotalWidth(SetTotalWidth);
            table.SetWidthPercentage(colSet, PageSize.A4);
            for (int i = 0; i < count; i++)
            {
                table.AddCell(GetPdfCell(content[i], font, horizontalAlignment[i], BorderSide[i]));
            }
            return table;
        }
        #endregion

        #region 生成单元格
        private static PdfPCell GetPdfCell(string content, Font font, int horizontalAlignment, int BorderSide)
        {
            PdfPCell cell = new PdfPCell(new Paragraph(content, font));
            cell.HorizontalAlignment = horizontalAlignment;//水平位置
            cell.VerticalAlignment = Element.ALIGN_CENTER;//垂直居中
            cell.MinimumHeight = 18;//单元格的最小高度
            cell.NoWrap = false;
            cell.DisableBorderSide(BorderSide);
            return cell;
        }
        #endregion

        //四种字体
        private static Font fontMiddle = new Font(titleBaseFont, 10, Font.BOLD);
        private static Font fontSmallNoBold = new Font(titleBaseFont, 10);
        private static float IndentationLeft = 0;//距左边距

        private static void AddPartnerContent(string[] Title, string[] Content)
        {
            fontMiddle.SetStyle(Font.UNDERLINE);//文字下划线
            Paragraph content = new Paragraph();
            content.IndentationLeft = IndentationLeft;
            int Total = 0;
            for (int i = 0; i < Title.Count(); i++)
            {
                Chunk chunkName = new Chunk(Title[i], fontSmallNoBold);
                Chunk chunkText = string.IsNullOrEmpty(Content[i]) ? new Chunk(GetEmptyString(6, " / "), fontMiddle) : new Chunk(GetEmptyString(Content[i].Length + 6, Content[i]), fontMiddle);
                content.Add(Total, chunkName);
                Total++;
                content.Add(Total, chunkText);
                Total++;
            }
            content.Alignment = 3;
            doc.Add(content);
        }
        //居中显示内容
        private static string GetEmptyString(int maxlength, string text)
        {
            int padding = (maxlength - text.Length * 2) / 2;
            string empty = string.Empty;
            for (int i = 0; i < padding; i++)
            {
                empty += " ";
            }
            return string.Format("{0}{1}{0}", empty, text);
        }
    }
}

